package gti310.tp3.parser;

import java.util.*;

/**
 * La classe E a pour but de stocker l’information extraite du fichier à 
 * l’entrée. On utilises Les listes adjancentes Liste et innerListe pour bien
 * organiser l'information des sommet et de leur connexions. Une liste séparée
 * peut être créée pour contenir que les sommets. 
 * 
 * @author Fredy A. Bonilla
 * @date 2014-11-10
 *
 */
public class E{
	
	//La liste principale et la liste imbriquée ainsi que les valeurs du graphe
	private List<List<Integer>> liste;
	private List<Integer> innerListe;
	private ArrayList<Integer> sources;
	private int nbrSommets = 0;
	private int valeurInfinie = 0;
	private int sommetDepart = 0;
	
	/**
	 * Constructeur de la classe E. Elle crée une nouvelle liste. 
	 */
	public E(){
		 liste = new ArrayList<List<Integer>>();
	}
	
	/************
	 * Acesseurs
	 ************/
	
	public List<List<Integer>> getListe(){
		return liste;
	}
	
	/**
	 * Retourne la innerListe à l'index reçu en paramètre. 
	 * 
	 * @param index de l'élément désiré
	 * @return l'élément désiré
	 */
	public List<Integer> getInnerListe(int index){
		return liste.get(index);
	}
	
	/**
	 * Retourne le nombre de sommets
	 * @return nbrSommets
	 */
	public int getNbrSommets() {
		return nbrSommets;
	}

	/**
	 * Retourne la valeur infinie
	 * @return valeurInfinie
	 */
	public int getValeurInfinie() {
		return valeurInfinie;
	}

	/**
	 * Retourne le sommet de depart
	 * @return sommetDepart
	 */
	public int getSommetDepart() {
		return sommetDepart;
	}
	
	/************
	 * Mutateurs
	 ************/

	public void setNbrSommets(int nbrSommets) {
		this.nbrSommets = nbrSommets;
	}

	public void setValeurInfinie(int valeurInfinie) {
		this.valeurInfinie = valeurInfinie;
	}

	public void setSommetDepart(int sommetDepart) {
		this.sommetDepart = sommetDepart;
	}

	/************
	 * Méthodes
	 ************/

	/**
	 * Cette méthode creer une nouvelle liste imbriquée qui est ensuite insérée
	 * dans la liste principale. 
	 */
	public void createInnerList(){
		innerListe = new ArrayList<Integer>(3);
		addInnerToList();
	}
	
	/**
	 * Ajoute l'élément à fin de la liste. S'il s'agit du premier élément, ce
	 * dernier est ajouter au début. 
	 * 
	 * @param element à ajouter
	 */
	public void ajouterElementInner(int element){
		innerListe.add(element);
	}
	
	/**
	 * Retourne la taille de la liste principale. 
	 * 
	 * @return la taille de la liste principale sous forme d'entier
	 */
	public int getTailleListe(){
		return liste.size();
	}
	
	/**
	 * Retourne la taille d'une liste imbriquée à une index de la liste 
	 * principale.
	 * 
	 * @param index de la liste principale
	 * @return la taille de la liste imbriquée
	 */
	public int getTailleInnerListe(int index){
		return liste.get(index).size();
	}
	
	/**
	 * La méthode parcours la liste principale et retient seulement les sommets
	 * sources. Elle retourne une nouvelle liste qui les contient. 
	 * 
	 * @return une liste des sommets sources seulement
	 */
	public ArrayList<Integer> getSources(){
		
		sources = new ArrayList<Integer>();
		
		for(int i=0; i<liste.size(); i++){
			
			if(sources.isEmpty()){
				sources.add(liste.get(i).get(0));
			}
			else if(!sources.contains(liste.get(i).get(0))){
				sources.add(liste.get(i).get(0));
			}
			
		}
		
		//Tri en ordre croissant, dans le cas qu'ils ne le sont pas. 
		Collections.sort(sources);
		
		return sources;
	}
	
	/**
	 * Retourne l'index de la valeur reçue.
	 * 
	 * @param val
	 * @return l'index de la valeur
	 */
	public int indexOf(int val){
		return sources.indexOf(val);
	}
	
	/**
	 * Méthode privée servant à l'ajout d'un innerListe dans la liste.
	 */
	private void addInnerToList(){
		liste.add(innerListe);
	}
	
	
	
}
